<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    input+input {
      margin-left: 10px;
    }
  </style>
</head>

<body>
  <!-- 准备好一个容器，承载整个react -->
  <div id="root"></div>

  <!-- react核心库 -->
  <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
  <!-- 支持react操作dom -->
  <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
  <!-- 将jsx转为js -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  <!-- 对组件标签属性进行限制 -->
  <script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>

  <script type="text/babel">
    class Count extends React.Component {
      state = {
        count: 1
      }
      render() {
        console.log('Count-render')
        return (
          <div>
            <h1>计数器：{this.state.count}</h1>
            <Son count={this.state.count} />
            <input type="button" value="点我+1" onClick={this.calculate(+1)} />
            <input type="button" value="点我-1" onClick={this.calculate(-1)} />
            <input type="button" value="强制更新状态" onClick={this.force} />
            <input type="button" value="卸载组件" onClick={this.unloadComponent} />
          </div>
        )
      }

      // 若state值在任何时候都取决于props，那么可以使用getDerivedStateFromProps；必须return状态或者null；挂载和更新组件之前都会调用
      static getDerivedStateFromProps(props, state) {
        // console.log(props, state)
        console.log('Count-getDerivedStateFromProps')
        return null
      }

      // 组件挂载完毕
      componentDidMount() {
        console.log('Count-componentDidMount-组件挂载完毕')
      }

      // 状态更新阀
      shouldComponentUpdate() {
        console.log('Count-shouldComponentUpdate-状态更新阀')
        return true
      }

      // 在更行之前获取快照
      getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log('Count-getSnapshotBeforeUpdate-在更行之前获取快照')
        return '厚礼蟹'
      }

      // 状态更新完成
      componentDidUpdate(prevProps, prevState, snapshot) {
        console.log(prevProps, prevState, snapshot)
        console.log('Count-componentDidUpdate-状态更新完成')
      }

      // 组件将要被卸载
      componentWillUnmount() {
        console.log('Count-componentWillUnmount-组件将要被卸载')
      }

      // 计算count
      calculate = (num) => {
        return () => {
          this.setState({
            count: this.state.count + num
          })
        }
      }

      force = () => {
        this.forceUpdate()
      }

      // 卸载组件
      unloadComponent = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById('root'))
      }

    }

    class Son extends React.Component {
      render() {
        console.log('Son-render')
        return (
          <h2>我是子组件，父组件的count为：{this.props.count}</h2>
        )
      }

      // 组件挂载完毕
      componentDidMount() {
        console.log('Son-componentDidMount-组件挂载完毕')
      }

      // 状态更新阀
      shouldComponentUpdate() {
        console.log('Son-shouldComponentUpdate-状态更新阀')
        return '厚礼蟹'
      }

      // 状态更新完成
      componentDidUpdate(prevProps, prevState, snapshot) {
        // console.log(prevProps, prevState, snapshot)
        console.log('Son-componentDidUpdate-状态更新完成')
      }

      // 组件将要被卸载
      componentWillUnmount() {
        console.log('Son-componentWillUnmount-组件将要被卸载')
      }

    }

    ReactDOM.render(<Count count={199} />, document.getElementById('root'))
  </script>
</body>

</html>